package org.windchill955.processplan;

import org.windchill955.NWTException;
import wt.fc.ObjectReference;
import wt.fc.ObjectToObjectLink;
import wt.fc.Persistable;
import wt.fc.collections.WTArrayList;
import wt.fc.collections.WTKeyedMap;
import wt.fc.collections.WTList;
import wt.util.WTException;
import wt.vc.struct.StructHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 工艺路线节点工具类
 *
 * @author pyk13
 * @version 0.1
 */
public class NodeUtil {

    /**
     * 根据父节点查询子节点
     *
     * @param linkClazz   父子关系链接类型Class
     * @param holderNodes 父节点集合
     * @param <LINKType>  类型
     * @return 子节点集合，包含了节点对象、父子关系
     */
    public static <LINKType extends ObjectToObjectLink> List<Node> findSubNodes(Class<LINKType> linkClazz, List<Node> holderNodes) {
        return findSubNodes(linkClazz, holderNodes.toArray(new Node[0]));
    }

    /**
     * 根据父节点查询子节点
     *
     * @param linkClazz  父子关系链接类型Class
     * @param holders    父节对象集合，可变参数
     * @param <LINKType> 类型
     * @return 子节点集合，包含了节点对象、父子关系
     */
    public static <LINKType extends ObjectToObjectLink> List<Node> findSubNodes(Class<LINKType> linkClazz, Persistable... holders) {
        List<Node> holderNodes = new ArrayList<>(holders.length);
        for (Persistable object : holders) {
            holderNodes.add(new Node(object));
        }
        return findSubNodes(linkClazz, holderNodes);
    }

    /**
     * 根据父节点查询子节点
     *
     * @param linkClazz   父子关系链接类型Class
     * @param holderNodes 父节点集合，可变参数
     * @param <LINKType>  类型
     * @return 子节点集合，包含了节点对象、父子关系
     */
    public static <LINKType extends ObjectToObjectLink> List<Node> findSubNodes(Class<LINKType> linkClazz, Node... holderNodes) {
        //工序 - 所在路径节点集合
        List<Node> subNodes = new ArrayList<>();
        if (holderNodes.length == 0) {
            return subNodes;
        }

        //把节点组装成object->node的map集合，方便子节点找到自己的父节点
        Map<Object, Node> holderMap = new HashMap<>();
        for (Node node : holderNodes) {
            holderMap.put(node.getRoleBObject(), node);
        }

        try {
            //批量查询子节点
            WTKeyedMap keyedMap = StructHelper.service.navigateUses(new WTArrayList(holderMap.keySet()), linkClazz, false);
            for (Object entryObj : keyedMap.entrySet()) {
                WTKeyedMap.WTEntry entry = (WTKeyedMap.WTEntry) entryObj;
                Persistable object = ((ObjectReference) entry.getKey()).getObject();
                Node parentNode = holderMap.get(object);

                WTList links = (WTList) entry.getValue();
                for (int i = 0; i < links.size(); i++) {
                    ObjectToObjectLink link = (ObjectToObjectLink) links.getPersistable(i);
                    Persistable roleBObject = link.getRoleBObject();
                    //将父子节点关联起来
                    Node childNode = new Node(link, roleBObject, parentNode);
                    holderMap.put(roleBObject, childNode);

                    subNodes.add(childNode);
                }
            }
        } catch (WTException e) {
            throw new NWTException("查询子节点出错", e);
        }
        return subNodes;
    }

}
